home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 201-220 / scopedisk214 / inquire / inquirepage.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  7KB  |  302 lines

  1.  
  2. /*
  3.  *  INQUIREPAGE.C
  4.  *
  5.  *  InquirePage -Ddevice -Uunit <pageno>
  6.  *
  7.  */
  8.  
  9. #include <exec/types.h>
  10. #include <exec/ports.h>
  11. #include <exec/io.h>
  12. #include <exec/memory.h>
  13. #include <devices/scsidisk.h>
  14. #include <libraries/dos.h>
  15. #include <libraries/dosextens.h>
  16. #include <libraries/filehandler.h>
  17. #include <clib/exec_protos.h>
  18. #include <clib/alib_protos.h>
  19. #include <ctype.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23.  
  24. typedef unsigned char ubyte;
  25.  
  26. typedef struct MsgPort    MsgPort;
  27. typedef struct IOStdReq IOStdReq;
  28. typedef struct IORequest IORequest;
  29. typedef struct SCSICmd    SCSICmd;
  30.  
  31. typedef struct SCSIReq {
  32.     IOStdReq sr_Req;
  33.     SCSICmd  sr_Cmd;
  34. } SCSIReq;
  35.  
  36. MsgPort *IoSink;
  37. SCSIReq Ios;
  38.  
  39. char *ErrorAry[] = {
  40.     "No Sense",
  41.     "Recovered Error",
  42.     "Not Ready",
  43.     "Medium Error",
  44.     "Hardware Error",
  45.     "Illegal Request",
  46.     "Unit Attention",
  47.     "Data Protect",
  48.     "Blank Check",
  49.     "Vendor Specific",
  50.     "Copy Aborted",
  51.     "Aborted Command",
  52.     "Equal (search_data)",
  53.     "Volume Overflow",
  54.     "MisCompare",
  55.     "Reserved"
  56. };
  57.  
  58. char *PeripheralType[] = {
  59.     "Direct Access Device (e.g. magnetic disk)",
  60.     "Sequential Access Device (e.g. magnetic tape)",
  61.     "Printer Device",
  62.     "Processor Device",
  63.     "Write-Once Device (e.g. WORM drive)",
  64.     "CD-ROM Device",
  65.     "Scanner Device",
  66.     "Optical Memory Device (e.g. optical disks)",
  67.     "Medium Changer Device (e.g. juke box)",
  68.     "Communications Device",
  69.     "TYPE 0x0A (Graphics Arts Pre-Press Devices)",
  70.     "TYPE 0x0B (Graphics Arts Pre-Press Devices)",
  71.     "TYPE 0x0C Reserved",
  72.     "TYPE 0x0D Reserved",
  73.     "TYPE 0x0E Reserved",
  74.     "TYPE 0x0F Reserved",
  75.     "TYPE 0x10 Reserved",
  76.     "TYPE 0x11 Reserved",
  77.     "TYPE 0x12 Reserved",
  78.     "TYPE 0x13 Reserved",
  79.     "TYPE 0x14 Reserved",
  80.     "TYPE 0x15 Reserved",
  81.     "TYPE 0x16 Reserved",
  82.     "TYPE 0x17 Reserved",
  83.     "TYPE 0x18 Reserved",
  84.     "TYPE 0x19 Reserved",
  85.     "TYPE 0x1A Reserved",
  86.     "TYPE 0x1B Reserved",
  87.     "TYPE 0x1C Reserved",
  88.     "TYPE 0x1D Reserved",
  89.     "TYPE 0x1E Reserved",
  90.     "TYPE 0x1F Unknown or no Device type"
  91. };
  92.  
  93. void myexit(void);
  94. int  InquirePage(short);
  95. int  SCSIOpen(char *, long);
  96. void SCSIClose(void);
  97. int  DoSCSI(char *, char *, long, ubyte, long *);
  98.  
  99. main(ac, av)
  100. char *av[];
  101. {
  102.     short pageNo[64];
  103.     short i;
  104.     short j;
  105.     char *deviceName = "scsi.device";
  106.     long unitNoBeg = -1;
  107.     long unitNoEnd = -1;
  108.  
  109.     atexit(myexit);
  110.  
  111.     IoSink = CreatePort(NULL, 0);
  112.  
  113.     for (i = 1, j = 0; i < ac; ++i) {
  114.     char *ptr = av[i];
  115.  
  116.     if (*ptr != '-') {
  117.         if (stricmp(ptr, "all") == 0) {
  118.         unitNoBeg = 0;
  119.         unitNoEnd = 7;
  120.         } else {
  121.         pageNo[j++] = strtol(ptr, NULL, 0);
  122.         }
  123.         continue;
  124.     }
  125.     ptr += 2;
  126.     switch(ptr[-1]) {
  127.     case 'D':
  128.         deviceName = (*ptr) ? ptr : av[++i];
  129.         break;
  130.     case 'U':
  131.         unitNoBeg = strtol((*ptr) ? ptr : av[++i], NULL, 0);
  132.         unitNoEnd = unitNoBeg;
  133.         break;
  134.     default:
  135.         puts("bad option");
  136.         break;
  137.     }
  138.     }
  139.     if (unitNoBeg < 0) {
  140.     puts("InquirePage [-D device] -U unit [page_number]");
  141.     puts("InquirePage all");
  142.     exit(0);
  143.     }
  144.     if (unitNoBeg != unitNoEnd && j == 0)
  145.     pageNo[j++] = 0;
  146.  
  147.     while (unitNoBeg <= unitNoEnd) {
  148.     if (SCSIOpen(deviceName, unitNoBeg) < 0) {
  149.         printf("Unable to open device %s unit %d\n", deviceName, unitNoBeg);
  150.     } else {
  151.         printf("DEVICE %s UNIT %d\n", deviceName, unitNoBeg);
  152.         if (j == 0) {
  153.         puts("  Reading all pages");
  154.         for (i = 0; i < 0x100; ++i)
  155.             InquirePage(i);
  156.         } else {
  157.         for (i = 0; i < j; ++i)
  158.             InquirePage(pageNo[i]);
  159.         }
  160.     }
  161.     ++unitNoBeg;
  162.     SCSIClose();
  163.     }
  164.     return(0);
  165. }
  166.  
  167. InquirePage(pageNo)
  168. short pageNo;
  169. {
  170.     __aligned char inquireSenseCmd[] = { 0x12, 0x00, pageNo, 0x00, 0xFF, 0x00 };
  171.     unsigned char buf[512];
  172.     int error;
  173.     long len;
  174.  
  175.     printf("    Inquire Page 0x%02x ", pageNo);
  176.     if (error = DoSCSI(inquireSenseCmd, buf, sizeof(buf), SCSIF_READ, &len)) {
  177.     char *errorStr = (error > 0 && error < 16) ? ErrorAry[error] : "?";
  178.     printf("error code %2d (0x%02x) %s\n", error, error, errorStr);
  179.     } else {
  180.     short i;
  181.     short j;
  182.  
  183.     printf("\n\t");
  184.     for (i = 0; i < len; ++i) {
  185.         if (i && (i & 7) == 0) {
  186.         printf("\t");
  187.         for (j = i - 8; j < i; ++j)
  188.             printf("%c", isprint(buf[j]) ? buf[j] : '-');
  189.         printf("\n\t");
  190.         }
  191.         printf(" %02x", buf[i]);
  192.     }
  193.     if (i) {
  194.         for (j = i; j & 7; ++j)
  195.         printf("   ");
  196.         printf("\t");
  197.         for (j = j - 8; j < i; ++j)
  198.         printf("%c", isprint(buf[j]) ? buf[j] : '-');
  199.     }
  200.     puts("");
  201.  
  202.     if (pageNo == 0) {
  203.         printf("\tPeripheral Device Type: %s\n", PeripheralType[buf[0] & 0x1F]);
  204.         printf("\tRelAdr:   %d (relative addressing mode supported)\n", (buf[7] & 128) ? 1 : 0);
  205.         printf("\tWBus32:   %d (32 bit wide transfers supported)\n", (buf[7] & 64) ? 1 : 0);
  206.         printf("\tWBus16:   %d (16 bit wide transfers supported)\n", (buf[7] & 32) ? 1 : 0);
  207.         printf("\tSync:     %d (synchronous transfers supported)\n", (buf[7] & 16) ? 1 : 0);
  208.         printf("\tLinked:   %d (linked commands supported)\n",       (buf[7] & 8 ) ? 1 : 0);
  209.         printf("\tReserved: %d\n", (buf[7] & 4) ? 1 : 0);
  210.         printf("\tCmdQue:   %d (tagged command queuing supported)\n",(buf[7] & 2 ) ? 1 : 0);
  211.         printf("\tSftRe:    %d (Soft-reset on RESET cond, else hard)\n", (buf[7] & 1) ? 1 : 0);
  212.     }
  213.     }
  214.     return(error);
  215. }
  216.  
  217. void
  218. myexit(void)
  219. {
  220.     SCSIClose();
  221.     if (IoSink)
  222.     DeletePort(IoSink);
  223. }
  224.  
  225.  
  226. int
  227. SCSIOpen(devName, unitNo)
  228. char *devName;
  229. long unitNo;
  230. {
  231.     int error;
  232.  
  233.     Ios.sr_Req.io_Message.mn_ReplyPort = IoSink;
  234.     if (error = OpenDevice(devName, unitNo, (IORequest *)&Ios.sr_Req, 0))
  235.     error = -1;
  236.     return(error);
  237. }
  238.  
  239. void
  240. SCSIClose()
  241. {
  242.     if (Ios.sr_Req.io_Device) {
  243.     CloseDevice((IORequest *)&Ios);
  244.     Ios.sr_Req.io_Device = NULL;
  245.     }
  246. }
  247.  
  248. int
  249. DoSCSI(cmd, buf, bytes, flags, len)
  250. char *cmd;
  251. char *buf;
  252. long bytes;
  253. ubyte flags;
  254. long *len;
  255. {
  256.     static ubyte senseCmd[] = { 0x03, 0x00, 0x00, 0x00, 20, 0 };
  257.     SCSIReq *ios = &Ios;
  258.     char senseBuf[20];
  259.     int error;
  260.  
  261.     ios->sr_Cmd.scsi_Command   = cmd;
  262.     ios->sr_Cmd.scsi_CmdLength = 6;
  263.     ios->sr_Cmd.scsi_Data   = buf;
  264.     ios->sr_Cmd.scsi_Length = bytes;
  265.     ios->sr_Cmd.scsi_Flags  = flags;
  266.  
  267.     ios->sr_Req.io_Command = 28;
  268.     ios->sr_Req.io_Data    = &ios->sr_Cmd;
  269.     ios->sr_Req.io_Length  = sizeof(ios->sr_Cmd);
  270.  
  271.     error = DoIO((IORequest *)&ios->sr_Req);
  272.     if (len)
  273.     *len = ios->sr_Cmd.scsi_Actual;
  274.  
  275.     switch(error) {
  276.     case 0:
  277.     break;
  278.     case HFERR_BadStatus:
  279.     ios->sr_Cmd.scsi_Command   = senseCmd;
  280.     ios->sr_Cmd.scsi_CmdLength = 6;
  281.     ios->sr_Cmd.scsi_Data    = (UWORD *)senseBuf;
  282.     ios->sr_Cmd.scsi_Length = sizeof(senseBuf);
  283.     ios->sr_Cmd.scsi_Flags    = SCSIF_READ;
  284.  
  285.     if (DoIO((IORequest *)&ios->sr_Req)) {
  286.         error = -256;
  287.         break;
  288.     }
  289.     if (ios->sr_Cmd.scsi_Actual < 4) {
  290.         error = -257;
  291.         break;
  292.     }
  293.     error = senseBuf[2];
  294.     break;
  295.     default:
  296.     error = -error;
  297.     break;
  298.     }
  299.     return(error);
  300. }
  301.  
  302.